package com.pi.common.annotation;

import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.pi.entity.DataSourceConfig;
import com.pi.service.DataSourceConfigService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import com.baomidou.dynamic.datasource.creator.DefaultDataSourceCreator;

import javax.sql.DataSource;

/**
 * @author TomFang
 * @version 1.0
 * @description: 多数据源切面处理
 * @date 2025/3/27 15:50
 */
@Aspect
@Component
@Order(0) // 请注意：这里order一定要小于tx:annotation-driven的order，即先执行DynamicDataSourceAspectAdvice切面，再执行事务切面，才能获取到最终的数据源
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class DataSourceAspect {

    protected final Logger log = LoggerFactory.getLogger(DataSourceAspect.class);

    @Autowired
    private DataSource dataSource;

    @Autowired
    private DefaultDataSourceCreator dataSourceCreator;

    @Autowired
    private DataSourceConfigService dataSourceConfigService;


    @Around("@annotation(ds)")
    public Object doAround(ProceedingJoinPoint jp, DS ds) throws Throwable {
        //切换数据源
        DynamicDataSourceContextHolder.clear();
        DynamicRoutingDataSource datasource = (DynamicRoutingDataSource) dataSource;
        log.info("当前数据库："+datasource.getDataSources().keySet());
        String dbName = ds.value();
        QueryWrapper<DataSourceConfig> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("data_source_name",dbName);
        DataSourceConfig dataSourceConfig = dataSourceConfigService.getOne(queryWrapper);
        if(dataSourceConfig != null){
            addDataSource(dataSourceConfig);
            DynamicDataSourceContextHolder.push(dbName);
        }
        log.info("切换后数据库："+datasource.getDataSources().keySet());
        return jp.proceed();
    }


    /**
     * 添加数据源的操作
     * @param dataSourceConfig 实体类
     */
    public void addDataSource(DataSourceConfig dataSourceConfig){
        DataSourceProperty property = new DataSourceProperty();
        property.setUrl(dataSourceConfig.getJdbcUrl()); //  jdbcUrl
        property.setDriverClassName(dataSourceConfig.getDriverClass()); //  驱动
        property.setUsername(dataSourceConfig.getUsername());   //  用户名
        property.setPassword(dataSourceConfig.getPassword());   //  密码

        DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource;
        DataSource dataSource = dataSourceCreator.createDataSource(property);
        //  加到数据源
        ds.addDataSource(dataSourceConfig.getDataSourceName(), dataSource);
    }
}
